#include "sprite.h"

#include <stdlib.h>
#include <time.h>

char *read_xpm(char *map[], int *wd, int *ht)
{
	__attribute__((unused)) static char read_xpm_jcard;
	int width, height, colors;
	char sym[256];
	int  col;
	int i, j;
	char *pix, *pixtmp, *tmp, *line;
	char symbol;

	// read width, height, colors
	if (sscanf(map[0],"%d %d %d", &width, &height, &colors) != 3) {
		printf("read_xpm: incorrect width, height, colors\n");
		return NULL;
	}
#ifdef DEBUG
	printf("%d %d %d\n", width, height, colors);
#endif
	if (width > HRES || height > VRES || colors > 256) {
		printf("read_xpm: incorrect width, height, colors\n");
		return NULL;
	}

	*wd = width;
	*ht = height;

	for (i=0; i<256; i++)
	sym[i] = 0;

	// read symbols <-> colors 
	for (i=0; i<colors; i++) {
		if (sscanf(map[i+1], "%c %d", &symbol, &col) != 2) {
			printf("read_xpm: incorrect symbol, color at line %d\n", i+1);
			return NULL;
		}
#ifdef DEBUG
		printf("%c %d\n", symbol, col);
#endif
		if (col > 256) {
			printf("read_xpm: incorrect color at line %d\n", i+1);
			return NULL;
		}
		sym[col] = symbol;
	}

	// allocate pixmap memory
	pix = pixtmp = malloc(width*height);

	// parse each pixmap symbol line
	for (i=0; i<height; i++) {
		line = map[colors+1+i];
#ifdef DEBUG
		printf("\nparsing %s\n", line);
#endif
		for (j=0; j<width; j++) {
			tmp = memchr(sym, line[j], 256);  // find color of each symbol
			if (tmp == NULL) {
				printf("read_xpm: incorrect symbol at line %d, col %d\n", colors+i+1, j);
				return NULL;
			}
			*pixtmp++ = tmp - sym; // pointer arithmetic! back to books :-)
#ifdef DEBUG
			printf("%c:%d ", line[j], tmp-sym);
#endif
		}
	}

	return pix;
}


Sprite * create_sprite(char *pic[], char *base,  int x, int y)
{
	/*creates a new sprite pointer*/
	Sprite *sp;
	sp= (Sprite*) malloc(sizeof(Sprite));
	/*inicializes position values*/
	sp->x=x;
	sp->y=y;
	/*inicializes random speeds*/
	srand(time(NULL));
	sp->xspeed = 0;
	sp->yspeed = 0;
	sp->newxspeed=sp->newyspeed=0;
	/*  width and height parameters*/
	int wd, hg;
	sp->map = read_xpm(pic, &wd, &hg); 
	/*updates width and height*/
	sp->width = wd;
	sp->height = hg;
	return sp;
}


void show_sprite(Sprite* fig, char* base) {
	
	int hg = fig->height;
	int wd = fig->width;
	char * mapinit=fig->map;
	int i,j;
	
	//if xspeed is greater than 0
	if (fig->xspeed>0)
	{
		for(j=fig->y;j<hg+fig->y; j++)
		for(i=fig->x; i<wd+fig->x; i++)
		
		set_pixel(i,j,*(fig->map++),base);
		
	}
	else
	{
		//if xspeed is lower than 0
		if (fig->xspeed<0)
		{
			for(j=fig->y;j<hg+fig->y; j++)
			for(i=wd+fig->x-1; i>=fig->x; i--)
			
			set_pixel(i,j,*(fig->map++),base);
			
		}
		//if xspeed is 0
		else
		{
			//if yspeed is greater than 0
			if (fig->yspeed>0)
			{

				int x=0;
				int y=0;
				for(j=fig->y;j<hg+fig->y; j++)
				{
					
					for(i=fig->x; i<wd+fig->x; i++)
					{		
						set_pixel(i,j,*(fig->map+49*y+x),base);
						y++;
					}
					x++;
					y=0;
				}
				
			}
			
			else
			{
				//if yspeed is lower than 0
				if (fig->yspeed<0)
				{
					
					
					int x=0;
					int y=0;
					for(j=hg+fig->y-1;j>=fig->y; j--)
					{
						for(i=fig->x; i<wd+fig->x; i++)
						{		
							set_pixel(i,j,*(fig->map+49*y+x),base);
							y++;
						}
						x++;
						y=0;
					}
				}
				//if yspeed is  0
				else
				{
					for(j=fig->y;j<hg+fig->y; j++)
					for(i=fig->x; i<wd+fig->x; i++)
					
					set_pixel(i,j,*(fig->map++),base);
				}
			}
		}
	}
	fig->map=mapinit;
	
}


void show_sprite_pos(Sprite* fig, int x, int y, char* base) {
	int i,j;
	fig->x=x;
	fig->y=y;
	char * mapinit=fig->map;
	for (i=0; i<fig->width; i++)
	for (j=0; j<fig->height; j++)
	set_pixel(j+x, i+y, *((fig->map)++),base);
	fig->map=mapinit;
}

int animate_sprite(Sprite *fig, char *base, int back, int type) {
	return 0;
}


void destroy_sprite(Sprite *fig, char *base, int back)
{
	/*indexes of sprite*/
	erase_sprite(fig, back, base);

	/* frees memory */
	free(fig);
	return;
}

void free_sprite(Sprite *fig)
{
	/* frees memory */
	free(fig);
}

void move_cursor(Sprite *fig, int xstep, int ystep, char *base, int back) {
	erase_sprite(fig, back, base);
	show_sprite_pos(fig,  xstep,  ystep,  base);	
}


void erase_sprite(Sprite* fig, int back, char* base) {
	int i,j;
	for(j=fig->y; j<fig->height+fig->y; j++) {			
		for(i=fig->x; i<fig->width+fig->x; i++) {
			set_pixel(i,j,back,base);
		}
	}
}

